package com.kk.demo.java8.frame.fel;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.greenpineyu.fel.Expression;
import com.greenpineyu.fel.FelEngine;
import com.greenpineyu.fel.FelEngineImpl;
import com.greenpineyu.fel.common.ObjectUtils;
import com.greenpineyu.fel.context.ContextChain;
import com.greenpineyu.fel.context.FelContext;
import com.greenpineyu.fel.context.MapContext;
import com.greenpineyu.fel.function.CommonFunction;
import com.greenpineyu.fel.function.Function;

public class FelDemo {

    private static final FelEngine fel = new FelEngineImpl();

    public static void runBase() {
        Object result = fel.eval("5000*12+7500");
        System.out.println(result);
    }

    public static void runBase2() {
        FelContext ctx = fel.getContext();
        ctx.set("单价", 5000);
        ctx.set("数量", 12);
        ctx.set("运费", 7500);
        Object result = fel.eval("单价*数量+运费");
        System.out.println(result);
    }

    public static void runbaseFun() {
        FelEngine fel = new FelEngineImpl();
        FelContext ctx = fel.getContext();
        Foo foo = new Foo();
        foo.setSize(1024);
        foo.setSample("sample");
        foo.setName("name");
        foo.setElName("elname");

        ctx.set("foo", foo);
        Map<String, String> m = new HashMap<String, String>();
        m.put("ElName", "fel");
        ctx.set("m", m);

        // 调用foo.getSize()方法。
        Object result = fel.eval("foo.size");

        System.out.println(result);

        // 调用foo.isSample()方法。
        result = fel.eval("foo.sample");
        System.out.println(result);

        // foo没有name、getName、isName方法
        // foo.name会调用foo.get("name")方法。
        result = fel.eval("foo.name");
        System.out.println(result);

        // m.ElName会调用m.get("ElName");
        result = fel.eval("m.ElName");
        System.out.println(result);
    }

    public static void felgetArray() {
        FelContext ctx = fel.getContext();

        // 数组
        int[] intArray = { 10, 2, 3 };
        ctx.set("intArray", intArray);
        // 获取intArray[0]
        String exp = "intArray[0]";
        System.out.println(exp + "->" + fel.eval(exp));
    }

    public static void getArrayList() {
        FelContext ctx = fel.getContext();
        // List
        List<Integer> list = Arrays.asList(11, 2, 3);
        ctx.set("list", list);
        // 获取list.get(0)
        String exp = "list[0]";
        System.out.println(exp + "->" + fel.eval(exp));

        // 集合
        Collection<String> coll = Arrays.asList("ac", "b", "c");
        ctx.set("coll", coll);
        // 获取集合最前面的元素。执行结果为"a"
        exp = "coll[0]";
        System.out.println(exp + "->" + fel.eval(exp));

        // 迭代器
        Iterator<String> iterator = coll.iterator();
        ctx.set("iterator", iterator);
        // 获取迭代器最前面的元素。执行结果为"a"
        exp = "iterator[1]";
        System.out.println(exp + "->" + fel.eval(exp));

        // Map
        Map<String, String> m = new HashMap<String, String>();
        m.put("name", "HashMap");
        ctx.set("map", m);
        exp = "map.name";
        System.out.println(exp + "->" + fel.eval(exp));

        // 多维数组
        int[][] intArrays = { { 11, 12 }, { 21, 22 } };
        ctx.set("intArrays", intArrays);
        exp = "intArrays[0][1]";
        System.out.println(exp + "->" + fel.eval(exp));

        // 多维综合体，支持数组、集合的任意组合。
        List<int[]> listArray = new ArrayList<int[]>();
        listArray.add(new int[] { 1, 2, 3 });
        listArray.add(new int[] { 4, 5, 6 });
        ctx.set("listArray", listArray);
        exp = "listArray[1][0]";
        System.out.println(exp + "->" + fel.eval(exp));
    }

    public static void runjava() {
        FelEngine fel = new FelEngineImpl();
        FelContext ctx = fel.getContext();
        ctx.set("out", System.out);
        fel.eval("out.println('Hello Everybody'.substring(6))");
    }

    public static void context() {
        // 负责提供气象服务的上下文环境
        FelEngine fel = new FelEngineImpl();
        String costStr = "成本";
        String priceStr = "价格";
        FelContext baseCtx = fel.getContext();
        // 父级上下文中设置成本和价格
        baseCtx.set(costStr, 50);
        baseCtx.set(priceStr, 100);

        String exp = priceStr + "-" + costStr;
        Object baseCost = fel.eval(exp);
        System.out.println("期望利润：" + baseCost);

        FelContext ctx = new ContextChain(baseCtx, new MapContext());
        // 通货膨胀导致成本增加（子级上下文 中设置成本，会覆盖父级上下文中的成本）
        ctx.set(costStr, 50 + 20);
        Object allCost = fel.eval(exp, ctx);
        System.out.println("实际利润：" + allCost);
    }

    public static void compileRun() {
        FelEngine fel = new FelEngineImpl();
        FelContext ctx = fel.getContext();
        ctx.set("a", 5000);
        ctx.set("b", 12);
        ctx.set("运费", 7500);
        Expression exp = fel.compile("(a == b and c == ) ? c : s", ctx);

        long startTime = System.currentTimeMillis();

        Object result = null;

        for (int i = 0; i < 100000000; i++) {
            ctx.set("单价", 5000 + i);
            ctx.set("数量", 12 + i);
            ctx.set("运费", 7500 + i);
            result = exp.eval(ctx);
        }

        long endTime = System.currentTimeMillis();
        System.out.println(result);
        System.out.println("时间:" + (endTime - startTime) / 1000.0f);
    }

    public static void functionRun() {
        // 定义hello函数
        Function fun = new CommonFunction() {

            public String getName() {
                return "hello";
            }

            /*
             * 调用hello("xxx")时执行的代码
             */
            @Override
            public Object call(Object[] arguments) {
                Object msg = null;
                if (arguments != null && arguments.length > 0) {
                    msg = arguments[0];
                }
                return ObjectUtils.toString(msg);
            }

        };
        FelEngine e = new FelEngineImpl();
        // 添加函数到引擎中。
        e.addFun(fun);
        String exp = "hello('fel')";
        // 解释执行
        Object eval = e.eval(exp);
        System.out.println("hello " + eval);
        // 编译执行
        Expression compile = e.compile(exp, null);
        eval = compile.eval(null);
        System.out.println("hello " + eval);
    }

    public static void main(String[] args) {
        compileRun();
    }

}
